home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BCI NET
/
BCI NET Dec 94.iso
/
archives
/
telecomm
/
bbs
/
ctdlaux_src.lha
/
aux.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-29
|
27KB
|
1,041 lines
/****************************************************************************
*
* Aux Handler V1.0 (c)Copyright 1987,1989 Steve Drew. All Rights Reserved.
*
* Aux-Handler Ver. 1.2 21-Dec-1989
*
* Steve Drew
* 216 MacEwan Valley Mews N.W.
* Calgary, Ab. Canada.
*
* |You may freely distribute this source as long as |
* |the Copyright notice is left intact. |
*
* Not for commercial use, unless approved by the author.
***************************************************************************/
/*
* Ver. 1.1 19-Oct-1989
*
* - Modified not to ignore null character when in RAW mode.
* - slightly modified read_ser() to ensure all console style handling
* is ignored in raw mode.
* - Added support for my AuxZmodem program (AZ). AZ sends AUX: an inhibit
* dos packet. AUX then cancels any reads to Serial port until AZ completes.
*
* Ver. 1.2 21-Dec-1989
*
* - don't have aux process hang around if SER: not available
* - fix sec/micros in waitforchar()
* - added carrier detection, if carrier disappears (was previously present )
* then throw away output, until carrier returns.
*
* ver 1.2a, 22-Apr-1992 did setparams to ensure XON/XOFF enabled.
*
* Ver 1.3 04-May-1992, added support for multi line cards.
* Ver 1.3a still trying to get multiline cards to work
* Ver 1.3b force XON flow control enabled.
* Ver 3.42L23 Setup for SAS/C and for use with Citadel
* Ver 3.42P15 Setup the serial port access like Citadel's
* so the GVP IOExtender would work... Also added a
* Debug Port option...
*/
#include "string.h"
#include <libraries/dos.h>
/*#include <ctype.h>*/
#include <devices/console.h>
#include <devices/serial.h>
#include <devices/timer.h>
#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <exec/tasks.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>
#include "proto/all.h"
#include "pragmas/dos_pragmas.h"
#include "pragmas/exec_pragmas.h"
#include "aux-debug.h"
int atoi(char *);
void _main(char *);
void chk_params ( char *str );
void chk_pend ( char *buf , struct DosPacket *pkt , struct Process *proc );
int read_ser ( char *buf );
void do_echo ( char *buf );
void set_read( void );
void write_ser ( char *buf , int len );
void puts_ser ( char *buf , int len );
int is_carrier ( void );
int open_devices ( void );
int open_serial ( void );
int open_timer ( void );
void close_devices ( void );
void parse_startup ( char *str );
void Aux_Debug(char *, int, int, int, int);
void returnpktplain ( struct DosPacket *packet , struct Process *myproc );
void returnpkt ( struct DosPacket *packet , struct Process *myproc , ULONG res1 , ULONG res2 );
struct DosPacket *taskwait ( struct Process *myproc );
struct DosLibrary *DOSBase;
struct DosLibrary *SYSBase;
#define DEVICE_NUMBER 0 /* serial device unit number to use */
#define DEVICE_NAME "serial.device" /* drive name for device */
typedef unsigned char u_char;
#undef BADDR
#define BADDR(x) ((APTR)((long)x << 2))
#define AUX_ECHO 1
#define AUX_CRLF 2
#define AUX_RAW 4
#define AUX_RPEND 8
#define AUX_WAIT_FOR 16
#define AUX_TYPEAHEAD_FULL 32
#define AUX_SER_QUEUED 64
#define AUX_MODEM 128
#define DOECHO (aux_stat & AUX_ECHO)
#define DOCRLF (aux_stat & AUX_CRLF)
#define ISRAW (aux_stat & AUX_RAW)
#define ISRPEND (aux_stat & AUX_RPEND)
#define ISWAITING (aux_stat & AUX_WAIT_FOR)
#define ISBUFFULL (aux_stat & AUX_TYPEAHEAD_FULL)
#define READINPROGRESS (aux_stat & AUX_SER_QUEUED)
#define ISMODEM (aux_stat & AUX_MODEM)
#define AUXBUFSIZE 256 /* Same as CON: handler */
#define MAXLINESIZE 254 /* save two for \n'\0' */
#define MYPORT_SIG (1L << myport->mp_SigBit)
#define READSER_SIG (1L << ReadSER->IOSer.io_Message.mn_ReplyPort->mp_SigBit)
#define TIMER_SIG (1L << Timer_Port->mp_SigBit)
/* My Globals */
struct MsgPort *mySerReadPort = NULL;
struct MsgPort *mySerWritePort = NULL;
struct IOExtSer *ReadSER = NULL;
struct IOExtSer *WriteSER = NULL;
struct timerequest *Timer;
struct MsgPort *Timer_Port;
struct Task *reader;
int aux_stat, aux_avail, in_len;
u_char in_c;
long device_number;
char *device_name;
long device_baud;
char *version = "\0$VER: Citadel Aux Handler 3.42P15 (12.30.93)";
void _main(arg)
char *arg; /* default parameter */
{
struct Process *myproc; /* my process */
struct DosPacket *mypkt; /* a pointer to the dos packet */
struct DosPacket *rdpkt;
struct DeviceNode *mynode; /* our device node (parmpkt Arg3) */
struct FileHandle *fh; /* a pointer to our file handle */
struct MsgPort *myport;
long run = TRUE; /* handler main loop flag */
u_char *ptr; /* ptr for name translation */
char *name,*s; /* ptr to name for open */
int aux_open = 0; /* aux open count */
char auxbuf[AUXBUFSIZE];/* Our type ahead buffer */
ULONG signals; /* signals that occurred in Wait */
char startup[100];
/* Initializing the handler */
DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 0L);
SYSBase = (struct DosLibrary *)OpenLibrary("exec.library", 0L);
myproc = (struct Process *)FindTask(0L);
Aux_Debug("Startup Message Wait...", (int)myproc, aux_stat, 0,FALSE);
mypkt = taskwait(myproc); /* Wait for my startup message */
rdpkt = mypkt;
mynode = (struct DeviceNode *)BADDR(mypkt->dp_Arg3);
mynode->dn_Task = &myproc->pr_MsgPort;
myport = &myproc->pr_MsgPort;
returnpkt(mypkt, myproc, DOSTRUE, mypkt->dp_Res2);
in_len = aux_avail = aux_stat = 0;
reader = (struct Task *) 0;
s = (char *)BADDR(mypkt->dp_Arg2) ; /* Arg2= BSTR to mountlist Startup */
if( s != NULL )
{
strncpy(startup,s+1,s[0]);
startup[s[0]] = '\0';
s = startup;
if (*s == '\"')
{
s++;
s[strlen(s)-1]= '\0' ;
};
}
else startup[0] = '\0';
/* set defaults */
device_name = DEVICE_NAME;
device_number = DEVICE_NUMBER;
device_baud = 0;
parse_startup(s);
/* done initial stuff, now for some work */
Aux_Debug(device_name, device_number, device_baud, 0,FALSE);
while(run)
{
if (aux_open)
{
/* then wait for read char or new action */
if (READINPROGRESS)
signals = Wait( MYPORT_SIG | READSER_SIG | TIMER_SIG );
else
signals = Wait( MYPORT_SIG );
if (signals & TIMER_SIG)
{
WaitIO((struct IORequest *)Timer);
Aux_Debug("Timer SIG...", signals, aux_stat, 0,FALSE );
aux_stat &= ~AUX_WAIT_FOR;
rdpkt->dp_Res1 = DOSFALSE;
returnpktplain(rdpkt,myproc);
}
if ((signals & READSER_SIG) && CheckIO((struct IORequest *)ReadSER))
{
Aux_Debug("READSER SIG...", signals, aux_stat, 0,FALSE);
read_ser(auxbuf);
chk_pend(auxbuf,rdpkt,myproc);
}
if (signals & MYPORT_SIG)
{
Aux_Debug("MYPORT_SIG...",signals,aux_stat,0,FALSE);
mypkt = taskwait(myproc);
}
else /* no new dospackets */
continue;
}
else /* only port at the moment is myport */
mypkt = taskwait(myproc);
Aux_Debug("dp_type...", signals, (int)mypkt, (int)mypkt->dp_Type,FALSE);
switch(mypkt->dp_Type)
{
/* find what action to perform */
case MODE_OLDFILE:
case MODE_NEWFILE:
/*
I allow for multiple writers. But only one process to read
at a time.
*/
if (!aux_open)
{
/* first time here we open the devices */
if (open_devices() == 0)
{
Aux_Debug("Error... open_device failed", 0, 0, 0,FALSE);
returnpkt(mypkt, myproc, DOSFALSE, ERROR_OBJECT_IN_USE);
run = 0; /* don't hang arround */
break;
}
}
aux_open++;
/*
* if baud specified in Startup message, set it here, else
* check filename for SET/ param later below.
*/
/* xxx */
/* get file name and Upper case it */
ptr = (u_char *)BADDR(mypkt->dp_Arg3);
name = (char *)AllocMem((long)*ptr + 1, MEMF_PUBLIC);
movmem(ptr+1, name, *ptr);
name[*ptr] = '\0';
for (s = name; *s; ++s)
{
*s = (*s >= 'a' && *s <= 'z') ? (*s - 'a' + 'A') : *s;
};
/*
This is a Hack to allow a bail out of a NEWCLI
that is using the AUX. By doing say an echo >AUX:ENDCLI
from another process the reader (being the NEWCLI)
will be sent a ENDCLI command.
*/
Aux_Debug(name, ISRPEND, aux_stat, 0,FALSE);
for (s = name; *s; ++s) if (*s == ':') break;
if (!strcmp(s,":ENDCLI") && (ISRPEND))
{
strcpy((char *)rdpkt->dp_Arg2,"ENDCLI\n");
rdpkt->dp_Res1 = 7L;
returnpktplain(rdpkt, myproc);
aux_stat &= ~AUX_RPEND;
}
else
chk_params(name);
FreeMem(name, (long)*ptr +1);
fh = (struct FileHandle *)BADDR(mypkt->dp_Arg1);
fh->fh_Arg1 = DOSTRUE;
fh->fh_Port = (struct MsgPort *)DOSTRUE;
if (mypkt->dp_Type == MODE_OLDFILE)
{
struct MsgPort *port;
port = mypkt->dp_Port;
if (reader && port->mp_SigTask != reader)
{
returnpkt(mypkt, myproc, DOSFALSE, ERROR_OBJECT_IN_USE);
--aux_open;
break;
}
reader = port->mp_SigTask;
fh->fh_Arg1 = (long)port->mp_SigTask;
}
returnpkt(mypkt, myproc, DOSTRUE, mypkt->dp_Res2);
break;
case ACTION_READ:
set_read();
rdpkt = mypkt;
aux_stat |= AUX_RPEND;
do_echo(auxbuf);
chk_pend(auxbuf,rdpkt,myproc);
Aux_Debug("ACTION_READ", 0, aux_stat, 0,FALSE);
break;
case ACTION_WRITE:
write_ser((char *)mypkt->dp_Arg2,(int)mypkt->dp_Arg3);
mypkt->dp_Res1 = mypkt->dp_Arg3; /* tell em we wrote them all */
returnpktplain(mypkt, myproc);
Aux_Debug("ACTION_WRITE", 0, aux_stat, 0,FALSE);
break;
case ACTION_WAIT_CHAR:
/* just queue up to wait for data */
set_read();
rdpkt = mypkt;
aux_stat |= AUX_WAIT_FOR;
if (rdpkt->dp_Arg1 >= 1000000L)
{
Timer->tr_time.tv_secs = rdpkt->dp_Arg1 / 1000000L;
Timer->tr_time.tv_micro = rdpkt->dp_Arg1 % 1000000L;
}
else
{
Timer->tr_time.tv_secs = 0L;
Timer->tr_time.tv_micro = rdpkt->dp_Arg1;
}
SendIO((struct IORequest *)Timer);
chk_pend(auxbuf,rdpkt,myproc);
Aux_Debug("ACTION_WAIT_CHAR", 0, aux_stat, 0,FALSE);
break;
case ACTION_SCREEN_MODE:
if (mypkt->dp_Arg1)
{
aux_stat |= AUX_RAW;
aux_stat &= ~AUX_ECHO;
}
else
{
aux_stat &= ~AUX_RAW;
aux_stat |= AUX_ECHO;
}
chk_pend(auxbuf,rdpkt,myproc);
returnpkt(mypkt, myproc, DOSTRUE, mypkt->dp_Res2);
Aux_Debug("ACTION_SCREEN_MODE", 0, aux_stat, 0,FALSE);
break;
case ACTION_END:
if (--aux_open == 0)
{
run = 0;
close_devices();
reader = (struct Task *) 0L;
}
returnpkt(mypkt, myproc, DOSTRUE, mypkt->dp_Res2);
Aux_Debug("ACTION_END", 0, aux_stat, 0,FALSE);
break;
case ACTION_INHIBIT:
if (READINPROGRESS)
{
AbortIO((struct IORequest *)ReadSER);
Wait(READSER_SIG);
WaitIO((struct IORequest *)ReadSER);
aux_stat &= ~AUX_SER_QUEUED;
}
returnpkt(mypkt, myproc, DOSTRUE, mypkt->dp_Res2);
Aux_Debug("ACTION_INHIBIT", 0, aux_stat, 0,FALSE);
break;
default:
returnpkt(mypkt, myproc, DOSFALSE, ERROR_ACTION_NOT_KNOWN);
Aux_Debug("Default...", 0, aux_stat, 0,FALSE);
break;
}
}
/* end while */
mynode->dn_Task = FALSE;
CloseLibrary((struct Library *)DOSBase);
CloseLibrary((struct Library *)SYSBase);
}
/*
Allows some flexibilty to control the port.
Can dynamically change CRLF translation,
Echo or RAW mode on/off.
*/
void chk_params(str)
char *str;
{
char *ptr, *s;
int param, i=1;
Aux_Debug(str, 0, 0, 0,TRUE);
for (s = str; *s; ++s) if (*s == ':') break;
if (strncmp(str,":SET/",5)) return;
ptr = str + 8;
while(i)
{
for (s = ptr; *ptr && *ptr != '/'; ++ptr);
if (*ptr == '\0') i = 0;
*ptr = '\0';
str = s+2;
if (ptr > str)
{
switch (*s)
{
case 'E':
param = AUX_ECHO;
break;
case 'C':
param = AUX_CRLF;
break;
case 'R':
param = AUX_RAW;
break;
default:
param = 0;
break;
}
if (*str == 'O')
{
if (*(str+1) == 'N') aux_stat |= param;
else
if (*(str+1) == 'F') aux_stat &= ~param;
}
}
++ptr;
}
}
/*
Check our buf to see if we have a line to return yet. Or if raw mode
give 'em all we got.
*/
void chk_pend(buf,pkt,proc)
char *buf;
struct DosPacket *pkt;
struct Process *proc;
{
char *p;
int i=0;
Aux_Debug("chk_pend",in_len, aux_stat, aux_avail,FALSE);
if ((in_len && (ISRAW)) || aux_avail)
{
if (ISWAITING)
{
aux_stat &= ~AUX_WAIT_FOR; /* clear the wait_for */
pkt->dp_Res1 = DOSTRUE;
AbortIO((struct IORequest *)Timer);
Wait(TIMER_SIG);
WaitIO((struct IORequest *)Timer);
returnpktplain(pkt,proc);
}
else if (ISRPEND)
{
aux_stat &= ~AUX_RPEND; /* clear the pending read */
if (ISRAW)
{
aux_avail = 0; /* since we're sending all */
}
else
--aux_avail;
/* if in_len is zero, then aux_avail must of been
set up to force us here to reply with Res1 = 0;
thus actually returning an EOF.
*/
if (in_len)
{
for (i = 1,p = (char *) pkt->dp_Arg2;
((p[i-1] = buf[i-1]) != '\n' || ISRAW) &&
i < pkt->dp_Arg3 && i < in_len; ++i) ;
/* reader asked for less than 256 chars but no cr
was found. If not in raw mode then bump avail back
up since we still have the remaining CR terminated
line in buf[].
*/
if (p[i-1] != '\n' && !(ISRAW))
{
++aux_avail;
}
}
in_len -= i;
movmem(buf+i,buf,in_len);
set_read();
pkt->dp_Res1 = (long)i;
Aux_Debug(buf,in_len, aux_stat, aux_avail,TRUE);
returnpktplain(pkt,proc);
}
}
}
/*
Only called here if there really is a character waiting to be read.
*/
read_ser(buf)
char *buf;
{
char c;
int ignore = 1;
if( ReadSER == NULL )
{
if( reader )Signal(reader, SIGBREAKF_CTRL_C);
return 1;
};
Aux_Debug("read_ser before", in_c, aux_stat, ReadSER->IOSer.io_Error,FALSE);
WaitIO((struct IORequest *)ReadSER);
aux_stat &= ~AUX_SER_QUEUED;
c = in_c;
Aux_Debug("read_ser after", c, aux_stat, ReadSER->IOSer.io_Error,FALSE);
/* ^C typed so immediately send the signal */
if (c == 3)
{
if (reader)
Signal(reader,SIGBREAKF_CTRL_C);
}
/*
* in raw mode, no filtering is done.
*/
if (ISRAW)
{
if (in_len < MAXLINESIZE) buf[in_len++] = c;
set_read();
return(1);
}
switch(c)
{
case 3: /* already done above */
break;
case 4: /* ^D, send the signal if there is a reader */
if (reader)
Signal(reader,SIGBREAKF_CTRL_D);
break;
case 6: /* ^F, send the signal if there is a reader */
if (reader)
Signal(reader,SIGBREAKF_CTRL_F);
break;
case 28: /* ^\ so wipe out line and force EOF */
in_len = 0;
++aux_avail;
break;
case 13: /* Always convert ^M to newline chara */
case 10:
c = 10;
ignore = 0;
++aux_avail;
break;
case 8: /* BS */
case 127: /* DEL */
if (in_len && buf[in_len-1] != '\n')
{
--in_len;
write_ser("\b \b",3);
}
break;
case 24: /* ^X */
case 21: /* ^U */
while(in_len && buf[in_len-1] != '\n')
{
--in_len;
write_ser("\b \b",3);
}
break;
case 18: /* ^R */
if (ISRPEND)
{
write_ser("\n",1);
do_echo(buf);
}
break;
case 27: /* <ESC> */
break;
default:
ignore = 0;
break;
}
/*
* is it, a valid character
*/
if (ignore == 0)
{
/*
* Length is already at maximum, forget about this character
* and Beep the user.
*/
if (c != '\n' && in_len >= MAXLINESIZE)
{
write_ser("\007",1);
}
/*
* normal case, save and echo if applicable
*/
else
{
buf[in_len++] = c;
/*
* don't echo unless aux process has caught upto us.
* ie, simulate VMS terminal handler rather than unix or
* amigados con:. This makes it nicer to typeahead the next
* command without causing the output from the current command
* to stop, thus pausing the current command.
*/
if (DOECHO)
{
if (ISRPEND) write_ser(&c,1);
}
}
}
set_read();
}
/*
* Now ready to echo first line of typeahead, or possible retyping
* due to ^R command.
*/
void do_echo(buf)
char *buf;
{
int i;
if (DOECHO)
{
for(i = 0; i < in_len ; ++i)
{
if (buf[i] == '\n')
{
++i;
break;
}
}
if (i) write_ser(buf,i);
}
}
/*
Start a asynchronous Read request
*/
void set_read()
{
Aux_Debug("set_read", in_c, aux_stat, READINPROGRESS,FALSE);
if (!READINPROGRESS)
{
ReadSER->IOSer.io_Length = 1L;
ReadSER->IOSer.io_Command = CMD_READ;
ReadSER->IOSer.io_Data = (APTR) &in_c;
SendIO((struct IORequest *)ReadSER);
aux_stat |= AUX_SER_QUEUED;
}
}
void write_ser(buf,len)
char *buf;
int len;
{
int i,j;
Aux_Debug("write_ser", (int)buf, DOCRLF, len,FALSE);
buf[len] = '\0';
Aux_Debug(buf,len,0,0,TRUE);
if (DOCRLF)
{
/*
* rather than call the serial device for each character, write all
* characters upto newline then insert <CR><LF> and continue.
*/
for(j=i=0; i < len; ++i)
{
if (buf[i] == '\n')
{
puts_ser(&buf[j],(i-j));
puts_ser("\r\n",2); /* ensure <CR><LF> order */
j = i+1;
}
}
if (j < len)
puts_ser(&buf[j],(len-j));
}
else
{
puts_ser(buf,len);
}
}
void puts_ser(buf,len)
char *buf;
int len;
{
/*
* If carrier was present and now is'nt then discard characters until
* carrier returns
*/
if( WriteSER == NULL)return;
Aux_Debug("puts_ser", (int)buf, ISMODEM, len,FALSE);
if (len)
{
if (is_carrier() || !ISMODEM)
{
WriteSER->IOSer.io_Command = CMD_WRITE;
WriteSER->IOSer.io_Length = (long)len;
WriteSER->IOSer.io_Data = (APTR) buf;
DoIO((struct IORequest *)WriteSER);
Aux_Debug("puts_ser:result", buf[0],WriteSER->IOSer.io_Error, len,FALSE);
}
}
}
/*
* return 0 if nocarrier
*/
is_carrier()
{
if( WriteSER == NULL ) return (0);
WriteSER->IOSer.io_Command = SDCMD_QUERY;
DoIO((struct IORequest *)WriteSER);
Aux_Debug("is_carrier", WriteSER->io_Status, aux_stat, WriteSER->IOSer.io_Error,FALSE);
if (!(WriteSER->io_Status & 0x20))
{
aux_stat |= AUX_MODEM;
return(1);
}
return(0);
}
open_devices()
{
ReadSER = WriteSER = NULL;
Timer_Port = NULL;
Timer = NULL;
aux_stat = AUX_ECHO | AUX_CRLF; /* set the default */
if (open_serial() && open_timer())
{
set_read();
return(1);
}
close_devices();
return(0);
}
/*
* open serial device
*/
open_serial()
{
if( (mySerReadPort = CreatePort(NULL,NULL)) != NULL)
{
Aux_Debug("open_serial",0 ,(int)mySerReadPort ,0 ,FALSE);
ReadSER = (struct IOExtSer *)CreateExtIO(mySerReadPort, sizeof(struct IOExtSer));
if( ReadSER != NULL )
{
Aux_Debug("open_serial",1 ,(int)ReadSER,0 ,FALSE);
if( (mySerWritePort = CreatePort(NULL,NULL)) != NULL )
{
Aux_Debug("open_serial",2 ,(int)mySerWritePort,0 ,FALSE);
WriteSER = (struct IOExtSer *)CreateExtIO(mySerWritePort, sizeof(struct IOExtSer));
if( WriteSER != NULL)
{
ReadSER->io_SerFlags = SERF_RAD_BOOGIE|SERF_SHARED|SERF_XDISABLED|SERF_7WIRE;
Aux_Debug("open_serial",3 ,(int)WriteSER,0 ,FALSE);
if ( !OpenDevice(device_name,device_number,(struct IORequest*)ReadSER,NULL) )
{
WriteSER->io_SerFlags = SERF_RAD_BOOGIE|SERF_SHARED|SERF_XDISABLED|SERF_7WIRE;
Aux_Debug("open_serial",4 ,(int)ReadSER->IOSer.io_Error,0 ,FALSE);
if ( !OpenDevice(device_name,device_number,(struct IORequest *)WriteSER,NULL) )
{
Aux_Debug("open_serial",5 ,(int)WriteSER->IOSer.io_Error ,0 ,FALSE);
return 1;
}
else
{
CloseDevice((struct IORequest *)ReadSER); /* extra thing to do if error */
};
};
};
};
};
};
Aux_Debug("open_serial",-1 ,(int)mySerWritePort, (int)mySerReadPort ,FALSE);
if( WriteSER )DeleteExtIO((struct IORequest *)WriteSER);
if( mySerWritePort)DeletePort(mySerWritePort);
if( ReadSER )DeleteExtIO((struct IORequest *)ReadSER);
if( mySerReadPort )DeletePort(mySerReadPort);
WriteSER = NULL;
ReadSER = NULL;
mySerWritePort = NULL;
mySerReadPort = NULL;
return(0);
}
/*
* Open Timer.device
*/
open_timer()
{
if (Timer_Port = CreatePort (NULL, NULL))
{
Aux_Debug("open_timer",0 ,0 ,0 ,FALSE);
if ((Timer = (struct timerequest *)
CreateExtIO (Timer_Port, (long) sizeof (*Timer))) != NULL )
{
Aux_Debug("open_timer",1 ,0 ,0 ,FALSE);
if (!(OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *)Timer, 0L)))
{
Timer->tr_node.io_Command = TR_ADDREQUEST;
Timer->tr_node.io_Flags = 0;
Timer->tr_node.io_Error = 0;
Aux_Debug("open_timer",2 ,0 ,0 ,FALSE);
return(1);
}
}
}
Aux_Debug("open_timer",-1 ,(int)Timer_Port ,(int)Timer ,FALSE);
Timer->tr_node.io_Device = 0;
return(0);
}
void close_devices()
{
if (READINPROGRESS)
{
AbortIO((struct IORequest *)ReadSER);
Wait(READSER_SIG);
WaitIO((struct IORequest *)ReadSER);
}
if( ReadSER )
{
CloseDevice((struct IORequest *)ReadSER);
DeleteExtIO((struct IORequest *)ReadSER);
};
if( mySerReadPort )DeletePort(mySerReadPort);
if (WriteSER)
{
CloseDevice((struct IORequest *)WriteSER);
DeleteExtIO((struct IORequest *)WriteSER);
}
if( mySerWritePort)DeletePort(mySerWritePort);
if (Timer)
{
if (Timer->tr_node.io_Device)
CloseDevice ((struct IORequest *)Timer);
DeleteExtIO ((struct IORequest *)Timer);
}
WriteSER = NULL;
ReadSER = NULL;
mySerWritePort = NULL;
mySerReadPort = NULL;
if (Timer_Port)
DeletePort(Timer_Port);
Timer_Port = NULL;
Aux_Debug("close_device",0 ,0 ,0 ,FALSE);
}
/*
* in mountlist startup allow:
*
* startup = "DEVICE:serial.device/UNIT:0/BAUD:2400"
*/
void parse_startup(str)
char *str;
{
char *s = str;
char *arg,*value;
int more = 1;
if( s == NULL)return;
while(more)
{
for(arg = s; *s; ++s) if (*s == ':') break;
if (!*s) break;
*s = '\0';
++s;
for(value = s; *s; ++s) if (*s == '/') break;
if (!*s) more = 0;
*s = '\0';
++s;
if (strcmp("DEVICE",arg) == 0)
{
device_name = value;
}
else if (strcmp("UNIT",arg) == 0)
{
device_number = atoi(value);
}
else if (strcmp("BAUD",arg) == 0)
{
device_baud = atoi(arg);
}
}
}
void Aux_Debug(msg, int1, int2, int3, flag)
char *msg; /* the message to send */
int int1, int2, int3, flag; /* various integer data to send */
{
struct MsgPort *port;
char *mymessage;
struct debugmsg *temp;
Forbid();
port = FindPort(AUXDEBUGPORT); /* check to see if we have a port...*/
Permit();
if( !port )return; /* if no port, just exit */
temp = (struct debugmsg *)AllocMem(sizeof(struct debugmsg),0);
if(!temp) return;
mymessage = (char *)AllocMem(strlen(msg)+1,0); /* dynamic sizing */
if( mymessage == NULL)
{
FreeMem(temp, sizeof(struct debugmsg));
return;
};
strcpy(mymessage,msg);
temp->msg = mymessage;
temp->a = int1;
temp->b = int2;
temp->c = int3;
temp->flag = flag;
/*
** Setup the Message itself
*/
temp->ipc_Msg.mn_Node.ln_Type = NT_MESSAGE;
temp->ipc_Msg.mn_Length = sizeof(struct debugmsg);
temp->ipc_Msg.mn_ReplyPort = NULL;
/* safe send of a message. If Port exists, we send the
** packet and forget about it. If the Port does not exist
** we forget that the message even existed...
*/
Forbid();
port = FindPort(AUXDEBUGPORT);
if( port )
{
PutMsg(port,(struct Message *)temp);
}
else
{
FreeMem(temp->msg,strlen(msg)+1);
FreeMem(temp, sizeof(struct debugmsg));
}
Permit();
/*
** we do not wait for the message reply, in this case there is
** no reply done and all memmory is deallocated in the reciever.
*/
}
/* returnpkt() - packet support routine
* here is the guy who sends the packet back to the sender...
*
* (I modeled this just like the BCPL routine [so its a little redundant] )
*/
void returnpktplain(packet, myproc)
struct DosPacket *packet;
struct Process *myproc;
{
returnpkt(packet, myproc, packet->dp_Res1, packet->dp_Res2);
}
void
returnpkt(packet, myproc, res1, res2)
struct DosPacket *packet;
struct Process *myproc;
ULONG res1, res2;
{
struct Message *mess;
struct MsgPort *replyport;
packet->dp_Res1 = res1;
packet->dp_Res2 = res2;
replyport = packet->dp_Port;
mess = packet->dp_Link;
packet->dp_Port = &myproc->pr_MsgPort;
mess->mn_Node.ln_Name = (char *) packet;
mess->mn_Node.ln_Succ = NULL;
mess->mn_Node.ln_Pred = NULL;
PutMsg(replyport, mess);
Aux_Debug("Return Packet",(int)packet ,res1 ,res2, FALSE );
}
/*
* taskwait() ... Waits for a message to arrive at your port and
* extracts the packet address which is returned to you.
*/
struct DosPacket *
taskwait(myproc)
struct Process *myproc;
{
struct MsgPort *myport;
struct Message *mymess;
myport = &myproc->pr_MsgPort;
WaitPort(myport);
mymess = GetMsg(myport);
Aux_Debug("taskwait",(int)mymess ,0 ,0, FALSE );
return((struct DosPacket *)mymess->mn_Node.ln_Name);
}